import * as vscode from 'vscode';
import { createGunzip, gunzip, gzip } from 'zlib';
import readline from 'node:readline';
import { promisify } from 'util';
import { openDatabase } from '../db';

const gzipPromise = promisify(gzip);

export function convert() {
	const TITLE_LINE_SIZE = 50;
	const PREFIX = '^\\s*';
	const RULES = [
		'《[^》]+》',
		'.*第\\s*[0-9０１２３４５６７８９零〇一二三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+\\s*[卷章节篇部回讲话]',
		'[0-9]+',
		'[０１２３４５６７８９]+',
		'[零〇一二三四五六七八九十百千万]+',
		'[零壹贰叁肆伍陆柒捌玖拾佰仟万]+',
		'卷\\s*[0-9０１２３４５６７８９零〇一二三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]+',
		'前言|主?目录|序[章幕篇]?|引[子言]?|楔子|(内容)?简介|后记|附录?|番外|花絮',
		'Chapter\\s+[0-9]+',
	];
	const SUFFIX = '(?:[：、\\s]+\\S+|\\s*$)';
	const regex = new RegExp(`${PREFIX}(?:${RULES.join('|')})${SUFFIX}`, 'gmi');

	type BookInfo = { id: number; book_name: string; gzip_content: Buffer };

	vscode.window.withProgress({ location: vscode.ProgressLocation.Notification }, async (p) => {
		const db = openDatabase();
		const books = db.prepare<unknown[], BookInfo>('select id, book_name, gzip_content from tb_book').all();
		p.report({
			message: 'converting ...',
		});
		const processed = 0;
		const stmt = db.prepare('insert into tb_chapter(book_id, chapter, gzip_content) values (?,?,?)');
		for (const book of books) {
			// const file = fs.createWriteStream(path.join(os.homedir(), 'Documents', book.book_name + '.txt'));
			p.report({
				message: 'Convert 《' + book.book_name + '》...',
				increment: processed / books.length,
			});
			const unzip = createGunzip();
			// const unziped = await gunzipPromise(book.gzip_content);
			// const text = unziped.toString();
			const rl = readline.createInterface({
				input: unzip,
				crlfDelay: Infinity,
			});
			unzip.write(book.gzip_content);
			unzip.end();

			let chapter = '';
			let content = '';
			for await (const line of rl) {
				// await new Promise<void>((resolve, reject) => {
				// 	file.write(line + '\n', 'utf-8', (err) => {
				// 		if (err) {
				// 			reject(err);
				// 		} else {
				// 			resolve();
				// 		}
				// 	});
				// });
				if (line.trim().length <= TITLE_LINE_SIZE && regex.test(line)) {
					if (chapter || content) {
						const gzipedChapter = await gzipPromise(Buffer.from(content, 'utf-8'));
						stmt.run(book.id, chapter || book.book_name, gzipedChapter);
					}
					chapter = line;
					content = '';
				} else {
					content += line + '\n';
				}
			}
			if (chapter || content) {
				const gzipedChapter = await gzipPromise(Buffer.from(content, 'utf-8'));
				stmt.run(book.id, chapter || book.book_name, gzipedChapter);
			}
		}
		p.report({
			message: 'finished',
			increment: 100,
		});
	});
}
